#coding=utf=8
"""
读取INI文件的通用配置类
作者: KydGroups
版本: 0.0.1
完成日期: 2024-02-21
修改记录:
"""

import os #导入操作系统模块

class KydIni():
    """
    读取INI文件的通用配置类
    """
    def __init__(self, nDebug:int=0):
        """
        :DESCRIPTION:
            初始化函数
        :PARAMS:
            nDebug: 调试等级 <=0不显示调试信息 >=1显示调试信息 调用的类调试等级-1
        :RETURNS:
            nothing
        """
        self.__nDebug = nDebug #显示是否为调试模式
        self.__listEncoding = ['ASCII', 'Unicode', 'utf-8','UTF-8', 'utf-16', 'utf-32', 'GB2312', 'GBK', 'GB18030'] #常用字符编码格式
        self.__listFalseValue = ['0', 'No', 'no', 'false', 'False', False, None, 0] #假值对象
        self.__strFilePath = ""#文件路径
        self.__strEncoding = "utf-8"#字符编码
        self.__bChanged = False #数据是否已经改变,用于写入数据
        self.__listData = [] #保存数据列表


    def __DebugInfo(self, strInfo:str="", bError:bool=False):
        """
        :DESCRIPTION:
            显示调试信息
        :PARAMS:
            strInfo: 需要显示的调试信息
            bError: 是否需要显示警告色
        :RETURNS:
            nothing
        """
        if not strInfo:
            return False
        if self.__nDebug >= 1:
            if bError: #如果显示警告红色
                strInfo = "\033[5;31m" + strInfo + "\033[0m" #警告色使用红色
            print(strInfo)
            return True
        else:
            return False


    def ClearAll(self):
        """
        :DESCRIPTION:
            清除全部数据的函数
        :PARAMS:
            nothing
        :RETURNS:
            nothing
        """
        self.__strFilePath='' #清除文件路径
        self.__bChanged=False #重置数据改变标志
        self.__listData.clear() #清除数据列表
        return True


    def ReadFile(self, filePath:str="", encoding:str='utf-8'):
        """
        :DESCRIPTION:
            读取INI配置文件,这个函数主要负责对参数进行检查
            由__CreateIniData函数负责数据处理
        :PARAMS:
            filePath: ini文件路径,注意文件名称必须以.ini后缀结尾
            encoding: 文件编码格式
        :RETURNS:
            True:读取成功 False:文件不存在、文件名错误、读取失败
        """
        self.ClearAll() #清除当前的全部数据
        if not filePath: #如果没有传入参数
            self.__DebugInfo("KydIoIni---->>ReadFile 没有传入文件路径参数filePath", True)
            return False
        if not os.path.exists(filePath): #如果文件不存在
            self.__DebugInfo(("KydIoIni---->>ReadFile 传入文件%s 不存在!" % filePath), True)
            return False
        if filePath.find(".ini") == -1:#如果文件不是以.ini结尾
            self.__DebugInfo("KydIoIni---->>ReadFile 传入的文件路径不是ini后缀文件")
            return False
        if not encoding: #如果没有传入字符编码
            self.__DebugInfo("KydIoIni---->>ReadFile 使用默认字符编码utf-8")
            encoding = 'utf-8'
        else: #如果传入的字符编码
            if encoding not in self.__listEncoding: #如果字符编码不在规定范围内
                self.__DebugInfo(("KydIoIni---->>ReadFile 传入的字符编码%s 不合法!" % encoding))
                return False
        self.__strFilePath = filePath #设置文件路径
        self.__strEncoding = encoding #设置文件字符编码
        if self.__CreateIniData(): #如果创建数据列表成功
            if self.__nDebug >=1: #如果是调试模式,这里不能使用__DebugInfo函数
                for item in self.__listData:
                    print(item)
            return True
        else:
            return False


    def __CreateIniData(self):
        """
        :DESCRIPTION:
            创建Ini数据,这个函数是为了减少ReadFile函数长度而设置的
            注意,不用检查数据,由上位函数负责检查
        :PARAMS:
            nothing
        :RETURNS:
            True:读取成功 False:读取失败
        """
        try:
            listRead = []
            with open(self.__strFilePath, 'r', encoding=self.__strEncoding) as inifile: #读取文件
                listRead = inifile.readlines()
                if not listRead: #如果没有读取到数据
                    return False
                else:
                    nLen = len(listRead) #计算读取的数据长度
                    self.__DebugInfo(("共读取%d行数据!" % nLen))
                    nBegin = 0 #对数据段进行分隔的开始
                    nEnd = 0 #对数据进行分隔的结束
                    bNewSection = False #是否开始新段 
                    while nEnd < nLen: #循环开始
                        strLine = listRead[nEnd].strip() #获取一行数据
                        if not bNewSection:#没有开始新段
                            strSection = self.__IsSectionName(strLine) #检查是否为一个段的开始
                            if not strSection: #如果不是段的开始
                                if self.__IsRemark(strLine): #检查是否是注释信息
                                    self.__listData.append({'Type':'REMARK', 'Data':strLine[1:]})
                                else: #其它信息忽略
                                    pass
                            else: #如果是新段开始
                                bNewSection = True #表示有一个新段没有处理
                                nBegin = nEnd #标记一个新段的开始位置
                        else: #如果已经开始了新段
                            strSection = self.__IsSectionName(strLine) #检查是否为一个段的开始
                            if not strSection: #如果不是段的开始,则不处理
                                pass
                            else: #如果是一个段的开始,则生成段数据
                                nEnd -= 1 #行号减1
                                while self.__IsRemark( listRead[nEnd].strip() ): #向上循环检查是否为注释行
                                    nEnd -= 1 #逐行向上检查,直到不是单独的注释行
                                dictSection = self.__CreateSectionData(listRead[nBegin:(nEnd+1)]) #处理段数据
                                if not dictSection: #如果处理错误
                                    pass
                                else:
                                    self.__listData.append({'Type':'SECTION',
                                                            'Name': dictSection['Name'],
                                                            'Data':dictSection['Data']}) #添加段数据
                                bNewSection = False #重置新段标志
                        nEnd += 1 #增加一个行数
                    else: #循环结束判断是否还有数据没有处理
                        if bNewSection: #如果有新段没有处理
                            dictSection = self.__CreateSectionData(listRead[nBegin:]) #处理段数据
                            if not dictSection: #如果处理错误
                                pass
                            else:
                                self.__listData.append({'Type':'SECTION',
                                                        'Name': dictSection['Name'],
                                                        'Data':dictSection['Data']}) #添加段数据
        except:
            return False
        else:
            return True


    def __CreateSectionData(self, listData:list=[]):
        """
        :DESCRIPTION:
            生成段数据,由__CreateSectionData函数设置
        :PARAMS:
            listData: 段数据列表,第一行是段名称
        :RETURNS:
            dict:处理成功 None:处理失败,或没有数据
        """
        if not listData:
            return None
        nLen = len(listData) #获取数据长度
        strSection = self.__IsSectionName(listData[0].strip()) #检查段名
        if not strSection: #如果第一行不是段名
            return None
        else:
            dictSection = {} #生成段数据字典
            dictSection['Name'] = strSection #段名称
            listValue = [] #段中的数据
            for num in range(1, nLen): #循环处理数据
                strLine = listData[num].strip() #处理数据
                if self.__IsRemark(strLine): #如果是注释
                    listValue.append({'Type':'REMARK', 'Data':strLine[1:]})
                else: #如果不是注释行
                    tupOption = self.__IsOption(strLine) #处理选项值数据
                    if not tupOption: #如果不是选项值,则抛弃
                        pass
                    else: #如果是则添加选项值
                        listValue.append({'Type':'OPTION', 'Name':tupOption[0], 'Value':tupOption[1]})
            dictSection['Data'] = listValue 
        return dictSection


    def __IsSectionName(self, strLine:str=""):
        """
        :DESCRIPTION:
            判断一行读取的数据是否为段名称,如果是则返回段名
        :PARAMS:
            strLine: 读取的一行数据
        :RETURNS:
            None: 不是段名 STR:段名称
        """
        if not strLine: #如果没有传入参数
            return None
        if strLine[0] != '[': #如果不是段开始字符
            return None
        nEnd = strLine.find(']') #查找段名称结束字符位置
        if nEnd == -1: #如果没有结束字符
            return None
        else:
            return strLine[1:nEnd] #返回段名称


    def __IsRemark(self, strLine:str=''):
        """
        :DESCRIPTION:
            判断一行读取的数据是否为注释
        :PARAMS:
            strLine: 读取的一行数据
        :RETURNS:
            True:是 False:否
        """
        if not strLine:
            return False
        else: #如果传入了参数
            if strLine[0] == '#': #如果是以#号开始
                return True
            else:
                return False


    def __IsOption(self, strLine:str=""):
        """
        :DESCRIPTION:
            判断一行读取的数据是否为选项值,如果是则返回选项名、值对tupple
        :PARAMS:
            strLine: 读取的一行数据
        :RETURNS:
            None: 不是选项值 STR:选项我名、值对
        """
        if not strLine: #如果没有传入参数
            return None
        if strLine[0] == '[': #如果为段开始字符
            return None
        if strLine[0] == '#': #如果为注释开始字符
            return None
        nPos = strLine.find('=') #查找=号
        if nPos == -1: #如果没有到
            return None
        else:
            strName = strLine[:nPos].strip() #选项名称
            strValue = strLine[(nPos+1):].strip() #选项值
            return (strName, strValue)


    def __SearchSection(self, sectionName:str=""):
        """
        :DESCRIPTION:
            查找是否有该数据段
        :PARAMS:
            sectionName: 数据段名称
        :RETURNS:
            -1: 没有该段,或没有数据 >=0: 对应段字典在数据列表中的位置
        """
        if not sectionName: #如果没有传入参数
            self.__DebugInfo("KydIoIni---->>__SearchSection 没有传入段名称")
            return -1
        if not self.__listData: #如果没有数据
            self.__DebugInfo("KydIoIni---->>__SearchSection 当前类中没有数据")
            return -1
        else:
            nLen = len(self.__listData) #获到数据长度
            for nPos in range(nLen): #循环判断
                item = self.__listData[nPos]
                if item['Type'] == 'SECTION': #如果是段数据
                    if item['Name'] == sectionName: #如果段名称相同
                        return nPos
            self.__DebugInfo(("KydIoIni---->>__SearchSection 没有查找到段 %s 的数据!" % sectionName))
            return -1 #循环结束还没有发现


    def HasSection(self, sectionName:str=""):
        """
        :DESCRIPTION:
            判断是否有数据段
        :PARAMS:
            sectionName: 数据段名称
        :RETURNS:
            True:有 False:没有
        """
        if not sectionName: #如果没有传入参数
            self.__DebugInfo("KydIoIni---->>HasSection 没有传入参数sectionName!")
            return False
        if self.__SearchSection(sectionName) == -1:
            return False
        else:
            return True
        

    def HasOption(self, sectionName:str="", optionName:str=""):
        """
        :DESCRIPTION:
            判断数据段是否有该选项值
        :PARAMS:
            sectionName: 数据段名称
            optionName: 选项名称
        :RETURNS:
            True:有 False:没有
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>HasSection 没有传入参数sectionName!")
            return False
        if not optionName:
            self.__DebugInfo("KydIoIni---->>HasSection 没有传入参数optionName!")
            return False
        nPos = self.__SearchSection(sectionName)
        if nPos == -1: #如果没有该数据段
            return False
        else: #如果有数据段
            dictSection = self.__listData[nPos] #获取该数据段的值
            for item in dictSection['Data']: #判断数据段的每一行数据
                if item['Type'] == 'OPTION': #如果是选项值
                    if item['Name'] == optionName: #如果选项名称相同
                        return True
            else:
                return False


    def GetIniDataList(self):
        """
        :DESCRIPTION:
            获取配置文件中所有数据的列表
        :PARAMS:
            nothing
        :RETURNS:
            None:没有数据 List:段名列表,只有一个也是列表
        """
        return self.__listData


    def GetSectionDataList(self, sectionName:str=""):
        """
        :DESCRIPTION:
            获取配置文件中指定数据段的数据列表
        :PARAMS:
            sectionName: 段名称
        :RETURNS:
            None:没有数据 List:数据列表,只有一个也是列表
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>GetSectionDataList 没有传入参数sectionName!")
            return None
        nPos = self.__SearchSection(sectionName)
        if nPos == -1: #如果没有查找到对应的段
            return None
        else:
            return self.__listData[nPos]['Data']


    def GetAllSectionNames(self):
        """
        :DESCRIPTION:
            获取配置文件中所有数据段名称列表
        :PARAMS:
            nothing
        :RETURNS:
            None:没有数据 List:段名列表,只有一个也是列表
        """
        if not self.__listData: #如果没有数据
            self.__DebugInfo("KydIoIni---->>GetAllSectionNames 当前没有数据!")
            return None
        else:
            listReturn = []
            for item in self.__listData:
                if item['Type'] == 'SECTION': #如果是段数据
                    listReturn.append(item['Name'])
            return listReturn


    def GetSectionAllOptionNames(self, sectionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中所有选项名称列表
        :PARAMS:
            sectionName: 数据段名称
        :RETURNS:
            None: 该数据段没有选项 List:选项名称列表
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>GetSectionAllOptionNames 没有传入参数sectionName")
            return None
        nPos = self.__SearchSection(sectionName) #查找该数据段
        if nPos == -1: #如果没有该数据段
            return None
        else:
            dataSection = self.__listData[nPos]['Data'] #获取对应数据段
            listReturn = [] #返回数据列表
            for item in dataSection:
                if item['Type'] == "OPTION": #如果是选项值
                    listReturn.append(item['Name'])
            return listReturn


    def GetSectionTupleItems(self, sectionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中所有选项名、值对的Tuple列表
        :PARAMS:
            sectionName: 数据段名称
        :RETURNS:
            None: 没有该数据段或该数据段没有选项 List: Tuple列表
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>GetSectionTupleItems 没有传入参数sectionName")
            return None
        nPos = self.__SearchSection(sectionName) #查找该数据段
        if nPos == -1: #如果没有该数据段
            return None
        else:
            dataSection = self.__listData[nPos]['Data'] #获取对应数据段
            listReturn = [] #返回数据列表
            for item in dataSection: #循环检查选项内容
                if item['Type'] == 'OPTION': #如果是选项值
                    listReturn.append((item['Name'], item['Value']))
            return listReturn


    def GetSectionDictItems(self, sectionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中所有选项名、值对的字典
        :PARAMS:
            sectionName: 数据段名称
        :RETURNS:
            None: 没有该数据段或该数据段没有选项 Dict:数据字典
        """
        if not sectionName: #如果没有数据
            self.__DebugInfo("KydIoIni---->>GetSectionDictItems 没有传入参数sectionName")
            return None
        else:
            nPos = self.__SearchSection(sectionName) #查找该数据段
            if nPos == -1: #如果没有该数据段
                return None
            else:
                dataSection = self.__listData[nPos]['Data'] #获取对应数据段
                dictReturn = {} #返回数据列表
                for item in dataSection: #循环检查选项内容
                    if item['Type'] == 'OPTION': #如果是选项值
                        dictReturn[item['Name']] = item['Value']
                return dictReturn

        
    def GetOptionStringValue(self, sectionName:str="", optionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中选项字符串值
        :PARAMS:
            sectionName: 数据段名称
            optionName: 选项名称
        :RETURNS:
            None:无值、参数错误 Str:有值
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>GetOptionStringValue 没有传入参数sectionName")
            return None
        if not optionName:
            self.__DebugInfo("KydIoIni---->>GetOptionStringValue 没有传入参数OptionName")
            return None
        nPos = self.__SearchSection(sectionName) #查找该数据段
        if nPos == -1: #如果没有该数据段
            return None
        else: #如果有数据段
            dataSection = self.__listData[nPos]['Data'] #获取该数据段的值
            for item in dataSection: #循环检查是否有对应的数据段
                if item['Type'] == 'OPTION': #如果是选项值
                    if item['Name'] == optionName: #如果选项值相等
                        return item['Value']
            else: #循环完毕还没有查找到
                return None


    def GetOptionIntValue(self, sectionName:str="", optionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中选项整型值
        :PARAMS:
            sectionName: 数据段名称
            optionName: 选项名称
        :RETURNS:
            None:无值 Int:有值
        """
        strValue = self.GetOptionStringValue(sectionName, optionName) #获取字符串值
        if strValue is None: #如果没有查找到数据
            return None
        else: #如果查找到数据,则进行类型转换
            return int(strValue)


    def GetOptionFloatValue(self, sectionName:str="", optionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中选项浮点值
        :PARAMS:
            sectionName: 数据段名称
            optionName: 选项名称
        :RETURNS:
            None:无值 Float:有值
        """
        strValue = self.GetOptionStringValue(sectionName, optionName) #获取字符串值
        if strValue is None: #如果没有查找到数据
            return None
        else: #如果查找到数据,则进行类型转换
            return float(strValue)


    def GetOptionBooleanValue(self, sectionName:str="", optionName:str=""):
        """
        :DESCRIPTION:
            获取数据段中选项字符串值
        :PARAMS:
            sectionName: 数据段名称
            optionName: 选项名称
        :RETURNS:
            True: 1、Yes、True、非零值 False:0、No、False、None
        """
        strValue = self.GetOptionStringValue(sectionName, optionName) #获取字符串值
        if strValue is None: #如果没有查找到数据
            return False
        else:
            if strValue in self.__listFalseValue: #如果字符串值在假值列表中
                return False
            else: #其它情况
                return True

    
    def SetOptionValue(self, optionValue, sectionName:str="", optionName:str="", strRemark:str=""):
        """
        :DESCRIPTION:
            设置选项值,如果没有该段则添加段,如果没有选项则添加选项
        :PARAMS:
            optionValue: 选项值
            sectionName: 数据段名称
            optionName: 选项名称
            strRemark: 选项的注释,如果是新选项才会判断这个值,如果该选项已经有则不会处理这个参数
        :RETURNS:
            True:设置成功 False:设置失败
        """
        if optionValue is None: #如果该值为None则报错,为0、False都不能报错
            self.__DebugInfo("KydIoIni---->>SetOptionValue 没有传入参数optionValue", True)
            return False
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>SetOptionValue 没有传入参数sectionName", True)
            return False
        if not optionName:
            self.__DebugInfo("KydIoIni---->>SetOptionValue 没有传入参数optionName", True)
            return False
        nPos = self.__SearchSection(sectionName)
        if nPos == -1: #如果没有对应的段,则添加新段
            sectionNew = {}
            sectionNew['Type'] = 'SECTION'
            sectionNew['Name'] = sectionName
            if not strRemark: #如果没有注释内容
                sectionNew['Data'] = [{'Type':'OPTION', 'Name':optionName, 'Value':optionValue}]
            else:
                sectionNew['Data'] = [{'Type':'REMARK', 'Data':strRemark},
                                      {'Type':'OPTION', 'Name':optionName, 'Value':optionValue}]
            self.__listData.append(sectionNew) #将新的数据段添加进数据列表
        else: #如果有对应的数据段
            listData = self.__listData[nPos]['Data'] #获取该数据段的数据
            for item in listData: #循环判断是否有该数据
                if item['Type'] == 'OPTION': #如果是选项值
                    if item['Name'] == optionName: #如果是传入的选项名称
                        item['Value'] = optionValue #直接设置选项值
                        break #中断for循环
            else: #如果循环结束,没有对应的选项值,则需要添加
                if not strRemark: #如果没有注释内容
                    self.__listData[nPos]['Data'].append({'Type':'OPTION', 'Name':optionName, 'Value':optionValue})
                else:
                    self.__listData[nPos]['Data'].append({'Type':'REMARK', 'Data':strRemark})
                    self.__listData[nPos]['Data'].append({'Type':'OPTION', 'Name':optionName, 'Value':optionValue})
        self.__bChanged = True #设置数据改变标志
        return True


    def DelSection(self, sectionName:str="", bDelRemark:bool=True):
        """
        :DESCRIPTION:
            删除数据段
        :PARAMS:
            sectionName: 数据段名称
            bDelRemark: 是否删除段注释,如果该段的数据前面有注释,则删除注释
        :RETURNS:
            True:删除成功 False:删除失败
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>DelSection 没有传入参数sectionName", True)
            return False
        nPos = self.__SearchSection(sectionName) #查找是否有对应数据段
        if nPos == -1: #如果没有对应的数据段
            return False
        else:
            self.__listData.pop(nPos) #按索引删除数据段
            if bDelRemark: #如果需要删除注释
                nPos -= 1 #检查上一位是否为注释
                while True:
                    if nPos < 0: #如果越位
                        break #中断循环
                    if self.__listData[nPos]['Type'] == 'REMARK': #如果是注释
                        self.__listData.pop(nPos) #删除该行注释
                        nPos -= 1 #继续检查上一行是否为注释
                    else: #如果不是注释
                        break #中断循环
            self.__bChanged = True #设置数据改变标志
            return True


    def DelOption(self, sectionName:str="", optionName:str="", bDelRemark:bool=True):
        """
        :DESCRIPTION:
            删除选项
        :PARAMS:
            sectionName: 数据段名称
            optionName: 选项名称
            bDelRemark: 是否删除段注释,如果该段的数据前面有注释,则删除注释
        :RETURNS:
            True:删除成功 False:删除失败
        """
        if not sectionName:
            self.__DebugInfo("KydIoIni---->>DelOption 没有传入参数sectionName", True)
            return False
        if not optionName:
            self.__DebugInfo("KydIoIni---->>DelOption 没有传入参数optionName", True)
            return False
        nPos = self.__SearchSection(sectionName)
        if nPos == -1: #如果没有对应的数据段
            return False
        else:
            listData = self.__listData[nPos]['Data'] #获取对应的数据段
            nPos = 0  #选项值
            for nPos in range(len(listData)): #循环判断
                item = listData[nPos ] #获取该项的内容
                if item['Type'] == 'OPTION': #如果是选项值类型
                    if item['Name'] == optionName: #如果是对应的选项值,则中断循环
                        break
            if (0 <= nPos < len(listData)): #如果num在规定的范围内,即已经查找到该数据
                listData.pop(nPos ) #删除该选项值
                if bDelRemark:
                    nPos -= 1 #检查上一位是否为注释
                    while True:
                        if nPos < 0: #如果越位
                            break #中断循环
                        if listData[nPos]['Type'] == 'REMARK': #如果是注释
                            listData.pop(nPos) #删除该行注释
                            nPos -= 1 #继续检查上一行是否为注释
                        else: #如果不是注释
                            break #中断循环
                self.__bChanged = True #设置数据改变标志
                return True
            else:
                return False


    def WriteFile(self, filePath:str="", encoding:str="utf-8"):
        """
        :DESCRIPTION:
            将改变的数据写入文件
        :PARAMS:
            filePath: 文件路径,如果没有设置则检查读取的文件名
            encoding: 文件字符编码
        :RETURNS:
            True:写入成功 False:写入失败
        """
        writePath = "" #写入文件的路径
        writeEncoding = "" #写入文件的编码
        if not filePath: #如果没有传入文件名,则使用读取时的文件名
            if not self.__strFilePath: #如果没有读取文件名,则直接退出
                self.__DebugInfo("KydIOIni---->>WriteFile 没有传入参数filePath", True)
                return False
            else:
                writePath = self.__strFilePath
        else: #如果传入的参数
            if filePath[-4:] != '.ini': #如果文件名没有后缀
                writePath = filePath + '.ini'
            else:
                writePath = filePath
        if not encoding: #如果没有传入编码参数,则使用默认编码
            writeEncoding = self.__strEncoding
        else:
            writeEncoding = encoding
        if not self.__listData: #如果没有数据需要写入,则直接退出
            self.__DebugInfo("KydIOIni---->>WriteFile 没有数据可写入文件!", True)
            return False
        if not self.__bChanged: #如果数据没有改变,则直接退出
            self.__DebugInfo("KydIOIni---->>WriteFile 没有数据改变不需写入文件!")
            return True
        listWrite = [] #保存需要写入的数据
        for item in self.__listData: #循环处理每一个数据
            if item['Type'] == 'REMARK': # 如果该行是Remark
                listWrite.append(("#%s\n" % item['Data']))
            elif item['Type'] == 'SECTION': #如果是Section
                listWrite.append(("[%s]\n" % item['Name'])) #添加SectionName
                dataSection = item['Data'] #获取Section中的数据
                for data in dataSection: #循环处理Section中的数据
                    if data['Type'] == 'REMARK': #如果是Section中的Remark
                        listWrite.append(("#%s\n" % data['Data']))
                    elif data['Type'] == 'OPTION': #如果是Section中的option
                        listWrite.append(("%s=%s\n" % (data['Name'], self.__ValueToString(data['Value']))))
                    else: #Other
                        pass
                listWrite.append("\n") #每个Section结束添加一个空行分隔
            else: #其它情况
                pass
        if not listWrite: #如果没有需要写入的数据
            self.__DebugInfo("KydIOIni---->>WriteFile 数据没有转换成功,无法写入!", True)
            return False
        else: #如果有需要写入的数据,则去掉最后一个的空行
            listWrite.pop(-1)
        try:
            with open(writePath, 'w+', encoding=writeEncoding) as file:
                for line in listWrite:
                    file.write(line)
            print("%s 文件写入成功!" % writePath)
            return True
        except:
            self.__DebugInfo("KydIOIni---->>WriteFile 出现未知错误,无法写入!", True)
            return False


    def __ValueToString(self, var):
        """
        :DESCRIPTION:
            将值转换为字符串值
        :PARAMS:
            var: 传入的值
        :RETURNS:
            string: 传入的值
        """
        if var == None: #如果传入假值
            return "False"
        if isinstance(var, str): #如果传入的是字符串,则直接返回
            return var
        if isinstance(var, int): #如果传入的是整数
            return ("%d" % var)
        if isinstance(var, float): #如果传入的是浮点数
            return ("%f" % var)
        if var in self.__listFalseValue: #其它情况,判断是否为假值
            return "False"
        else:
            return "True"
